package org.javahispano.javacup.tacticas_aceptadas.sjvc;
import org.javahispano.javacup.modelo.*;

import java.util.List;

public abstract class SubTactica {

	protected int iteraciones;
	protected int iteracionesConsecutivas;
	protected int ultimaIteracion;
	protected int golesPropios;
	protected int golesRival;
	protected int vecesUsada;
	
	public SubTactica(){
		iteracionesConsecutivas = 0;
		iteraciones = 0;
		ultimaIteracion = -1;
		golesPropios = 0;
		golesRival = 0;
		vecesUsada = 0;
	}
	
	public int iteraciones(){
		return iteraciones;
	}
	
	public int iteracionesConsecutivas(){
		return iteracionesConsecutivas;
	}
	
	public int golesPropios(){
		return golesPropios;
	}
	
	public int golesRival(){
		return golesRival;
	}
	
	public int vecesUsada(){
		return vecesUsada;
	}
	
	//Va de -1 a 1
	public double factorUsabilidad(SituacionPartido sp){
		return (golesPropios - golesRival) / (golesPropios + golesRival > 0 ? (golesPropios + golesRival) : 1);
	}
	
	public List<Comando> ejecutar(SituacionPartido sp, SituacionPartidoSergio spAnterior){
					
		//Incremento el n� de veces que se ha usado esta subt�tcica (si procede)
		if(spAnterior == null || ultimaIteracion != spAnterior.iteracion()){
			vecesUsada++;
			iteracionesConsecutivas = 0;
		}
		
		//Incremento el n� de iteraciones que se ha usado esta subt�ctica
		iteracionesConsecutivas++;
		iteraciones++;
		
		//Incremento el n� de goles (si procede)
		if(spAnterior != null){
			if(spAnterior.golesPropios() < sp.golesPropios())
				golesPropios++;
			else if(spAnterior.golesRival() < sp.golesRival())
				golesRival++;
		}
		
		//Guardo la �ltima iteraci�n en la que se ha usado esta t�ctica
		ultimaIteracion = sp.iteracion();
		
		//Ejecuta el c�digo de la t�ctica
		return _ejecutar(sp, spAnterior);
	}
	
	protected abstract List<Comando> _ejecutar(SituacionPartido sp, SituacionPartidoSergio spAnterior);
	
	public static int ObtenerLaMejor(List<SubTactica> tacticas, SituacionPartido sp, int tacticaEnUso){
		return ObtenerLaMejor(tacticas, sp, tacticaEnUso, false);		
	}
	
	public static int ObtenerLaMejor(List<SubTactica> tacticas, SituacionPartido sp, int tacticaEnUso, boolean excluirTacticaEnUso){
		if(tacticas == null || tacticas.size() == 0)
			return -1;
		
		//Considero que la mejor es la que estoy usando (si no estoy usando, la 0)
		//Si tengo que excluir, cogeré la primera que no esté usando (sólo si hay más de 1 táctica)
		int mejor =  tacticaEnUso >= 0 ? (excluirTacticaEnUso ? (tacticas.size() > 1 ? (tacticaEnUso == 0 ? 1 : 0) : 0) : tacticaEnUso) : 0;

		//Busco la mejor
		for(int i = 0; i < tacticas.size(); i++)
        	if((!excluirTacticaEnUso || i!=tacticaEnUso) && tacticas.get(i).factorUsabilidad(sp) > tacticas.get(mejor).factorUsabilidad(sp))
        		mejor = i; 
        
        return mejor;
	}
}